home *** CD-ROM | disk | FTP | other *** search
/ Joystick Magazine 1996 May / cd joy 71No13.iso / pc / demos / eurosoc / source / unmangle.c < prev    next >
C/C++ Source or Header  |  1995-01-16  |  11KB  |  500 lines

  1. /* UNMANGLE 13/11/94 for WATCOM C
  2.  * Assumes Intel data in mangled file (no method set in mangle)
  3.  * Converted by P.Hiley.
  4.  * Modified by Kevin Dudley.
  5.  */
  6.  
  7. #include <conio.h>
  8. #include <errno.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "unmangle.h"
  14.  
  15. //************************************************************************************************
  16. //
  17. // UnMangle from Memory to Memory
  18. //
  19. // unsigned char *source - pointer to start of unmangled data (not the header)
  20. // unsigned char *dest - pointer to area of memory for destination (make sure it is big enough)
  21. //
  22. // returns - length of data
  23. // 
  24. //************************************************************************************************
  25.  
  26. extern long int UnMangleMemToMem(unsigned char *source, unsigned char *dest)
  27.     {
  28.  
  29.     int c;
  30.     int u,v;
  31.     unsigned char *pt;
  32.     unsigned char *start=dest;
  33.  
  34.     while ((c=*source++)!=0)
  35.         {
  36.         if (c & 128)
  37.             {
  38.             // Bit 7 : 1 : BLOCK
  39.             if (c & 64)
  40.                 {
  41.                 // Bit 6 : 1 Block size
  42.                 if (c & 32)
  43.                     {
  44.                     // Bit 5 : 1 Long
  45.                     pt= dest-((c & 31)<<8) -*source++ -3;    // offset
  46.                     c= *source++ + 5;                        // size
  47.                     while (c--)
  48.                         *dest++=*pt++;
  49.                     }
  50.                 else
  51.                     {
  52.                     // Bit 5 : 0 Medium
  53.                     pt= dest-((c & 3)<<8) -*source++ -3;    // offset
  54.                     c= ((c>>2) & 7) + 4;                    // size
  55.                     while (c--)
  56.                         *dest++=*pt++;
  57.  
  58.                     }
  59.                 }
  60.             else
  61.                 {
  62.                 // Bit 6 : 0 : Short
  63.                 pt= dest-(c & 63) -3;
  64.                 *dest    = *pt;
  65.                 *(dest+1)= *(pt+1);
  66.                 *(dest+2)= *(pt+2);
  67.                 dest+=3;
  68.                 }
  69.             }
  70.         else
  71.             {
  72.             // Bit 7 : 0
  73.             if (c & 64)
  74.                 {
  75.                 // Bit 6 : 1 Seq/Diff or String
  76.                 if (c & 32)
  77.                     {
  78.                     // Bit 5 : 1 : Sequence
  79.                         if (c & 16)
  80.                         {
  81.                         // Bit 4 : 1 : Word sequence
  82.                         c= (c & 15) + 2;    // bits 3-0 = len 2->17
  83.                         v= *(short *)(dest-2);
  84.                         while (c--)
  85.                             {
  86.                             *(short *)dest=(short)v;
  87.                             dest+=2;
  88.                             }
  89.                         }
  90.                     else
  91.                         {
  92.                         // Bit 4 : 0 : Byte sequence
  93.                         c= (c & 15) + 3;    // bits 3-0 = len 3->18
  94.                         v= *(dest-1);
  95.                         while (c--)
  96.                             *dest++=(signed char) v;
  97.                         }
  98.                     }
  99.                 else
  100.                     {
  101.                     // Bit 5 : 0 : Difference
  102.                         if (c & 16)
  103.                         {
  104.                         // Bit 4 : 1 : Word difference
  105.                         c= (c & 15) + 2;            // bits 3-0 = len 2->17
  106.                         u= *(short *)(dest-2);        // start word
  107.                         v= u -*(short *)(dest-4);    // dif
  108.                         while (c--)
  109.                             {
  110.                             u+=v;
  111.                             *(short *)dest=(short)u;
  112.                             dest+=2;
  113.                             }
  114.                         }
  115.                     else
  116.                         {
  117.                         // Bit 4 : 0 : Byte difference
  118.                         c= (c & 15) + 3;    // bits 3-0 = len 3->18
  119.                         u= *(dest-1);        // start byte
  120.                         v= u - *(dest-2);    // dif
  121.                         
  122.                         while (c--)
  123.                             {
  124.                             u+=v;
  125.                             *dest++=(char)u;
  126.                             }
  127.                         }
  128.                     }
  129.                 }
  130.             else
  131.                 {
  132.                 // Bit 6 : 0 : String
  133.                 c &= 63;    // len
  134.                 memcpy(dest,source,c);
  135.                 dest+=c;
  136.                 source+=c;
  137.                 }
  138.             }
  139.         }
  140.     return (dest-start);
  141.     }
  142.  
  143. //************************************************************************************************
  144. //
  145. // UnMangle from File to Memory
  146. //
  147. // *srcfile -     pointer to the source filename (make sure there is no header)
  148. // *dest - pointer to area of memory for destination (make sure it is big enough)
  149. //
  150. // returns    - Negative on error
  151. //
  152. //************************************************************************************************
  153.  
  154. unsigned char *unmanglebuf;
  155. unsigned char *unmangleinbuf;
  156. unsigned char *unmangledst;            // unmangle output address into it's buffer
  157. unsigned long unmangleinpoff;            // offset position reading from mangled file
  158. unsigned long unmanglebufpos;            // offset position of input buffer in mangled file
  159. FILE *unmanglefile;
  160.  
  161. extern long int UnMangleFileToMem(char *srcfile,unsigned char *dest)
  162.     {
  163.  
  164.     int c;
  165.     int u,v;
  166.     unsigned char *pt;
  167.  
  168. // Initialise the unmangle
  169.  
  170.     unmanglebuf=(unsigned char *)malloc(LOOKBACK+BLOCKSIZE+260);
  171.     unmangleinbuf=(unsigned char *)malloc(INPUTBLOCK);
  172.  
  173.     unmanglefile=fopen(srcfile,"rb");
  174.  
  175.     unmangledst=dest;
  176.  
  177.     unmangleinpoff=0;
  178.     unmanglebufpos=0;
  179.  
  180.     fseek(unmanglefile,unmanglebufpos,SEEK_SET);
  181.     fread(unmangleinbuf,1,INPUTBLOCK,unmanglefile);
  182.  
  183. // Do the unmangle
  184.     for(;;)
  185.         {
  186.         c=*unmangleGet(unmangleinpoff++,1);
  187.         if (!c) break;        // done
  188.  
  189.         if (c & 128)
  190.             {
  191.             // Bit 7 : 1 : BLOCK
  192.             if (c & 64)
  193.                 {
  194.                 // Bit 6 : 1 Block size
  195.                 if (c & 32)
  196.                     {
  197.                     // Bit 5 : 1 Long
  198.                     pt= unmangledst-((c & 31)<<8) -*unmangleGet(unmangleinpoff++,1) -3;    // offset
  199.                     c= *unmangleGet(unmangleinpoff++,1) + 5;                        // size
  200.  
  201.                     while (c--)
  202.                         *unmangledst++=*pt++;
  203.                     }
  204.                 else
  205.                     {
  206.                     // Bit 5 : 0 Medium
  207.                     pt= unmangledst-((c & 3)<<8) -*unmangleGet(unmangleinpoff++,1) -3;    // offset
  208.                     c= ((c>>2) & 7) + 4;                    // size
  209.                     while (c--)
  210.                         *unmangledst++=*pt++;
  211.  
  212.                     }
  213.                 }
  214.             else
  215.                 {
  216.                 // Bit 6 : 0 : Short
  217.                 pt= unmangledst-(c & 63) -3;
  218.                 *unmangledst    = *pt;
  219.                 *(unmangledst+1)= *(pt+1);
  220.                 *(unmangledst+2)= *(pt+2);
  221.                 unmangledst+=3;
  222.                 }
  223.             }
  224.         else
  225.             {
  226.             // Bit 7 : 0
  227.             if (c & 64)
  228.                 {
  229.                 // Bit 6 : 1 Seq/Diff or String
  230.                 if (c & 32)
  231.                     {
  232.                     // Bit 5 : 1 : Sequence
  233.                         if (c & 16)
  234.                         {
  235.                         // Bit 4 : 1 : Word sequence
  236.                         c= (c & 15) + 2;    // bits 3-0 = len 2->17
  237.                         v= *(short *)(unmangledst-2);
  238.                         while (c--)
  239.                             {
  240.                             *(short *)unmangledst=(short)v;
  241.                             unmangledst+=2;
  242.                             }
  243.                         }
  244.                     else
  245.                         {
  246.                         // Bit 4 : 0 : Byte sequence
  247.                         c= (c & 15) + 3;    // bits 3-0 = len 3->18
  248.                         v= *(unmangledst-1);
  249.                         while (c--)
  250.                             *unmangledst++=(signed char) v;
  251.                         }
  252.                     }
  253.                 else
  254.                     {
  255.                     // Bit 5 : 0 : Difference
  256.                         if (c & 16)
  257.                         {
  258.                         // Bit 4 : 1 : Word difference
  259.                         c= (c & 15) + 2;            // bits 3-0 = len 2->17
  260.                         u= *(short *)(unmangledst-2);        // start word
  261.                         v= u -*(short *)(unmangledst-4);    // dif
  262.                         while (c--)
  263.                             {
  264.                             u+=v;
  265.                             *(short *)unmangledst=(short)u;
  266.                             unmangledst+=2;
  267.                             }
  268.                         }
  269.                     else
  270.                         {
  271.                         // Bit 4 : 0 : Byte difference
  272.                         c= (c & 15) + 3;    // bits 3-0 = len 3->18
  273.                         u= *(unmangledst-1);        // start byte
  274.                         v= u - *(unmangledst-2);    // dif
  275.                         
  276.                         while (c--)
  277.                             {
  278.                             u+=v;
  279.                             *unmangledst++=(char)u;
  280.                             }
  281.                         }
  282.                     }
  283.                 }
  284.             else
  285.                 {
  286.                 // Bit 6 : 0 : String
  287.                 c &= 63;    // len
  288.                 memcpy(unmangledst,unmangleGet(unmangleinpoff,c),c);
  289.                 unmangledst+=c;
  290.                 unmangleinpoff+=c;
  291.                 }
  292.             }
  293.         }
  294.  
  295.     fclose(unmanglefile);
  296.  
  297.     free(unmanglebuf);
  298.     free(unmangleinbuf);
  299.  
  300.     return(EZERO);
  301.     }
  302.  
  303. //************************************************************************************************
  304. //
  305. // UnMangle from file to another file
  306. //
  307. // *srcfile -     pointer to the source filename (make sure there is no header)
  308. // *destfile - name of destfile
  309. //
  310. // returns    - currently always zero
  311. //
  312. //************************************************************************************************
  313.  
  314.  
  315. extern long int UnMangleFileToFile(char *srcfile,char *destfile)
  316.     {
  317.  
  318.     int c;
  319.     int u,v;
  320.     int len;
  321.     unsigned char *pt;
  322.     FILE *outfile;
  323.  
  324.  
  325. // Initialise the unmangle
  326.  
  327.     unmanglebuf=(unsigned char *)malloc(LOOKBACK+BLOCKSIZE+260);
  328.     unmangleinbuf=(unsigned char *)malloc(INPUTBLOCK);
  329.  
  330.     unmanglefile=fopen(srcfile,"rb");
  331.  
  332.     outfile=fopen(destfile,"wb");
  333.     unmangledst=unmanglebuf+LOOKBACK;
  334.  
  335.     unmangleinpoff=0;
  336.     unmanglebufpos=0;
  337.  
  338.     fseek(unmanglefile,unmanglebufpos,SEEK_SET);
  339.     fread(unmangleinbuf,1,INPUTBLOCK,unmanglefile);
  340.  
  341. // Do the unmangle
  342.     for(;;)
  343.         {
  344.         c=*unmangleGet(unmangleinpoff++,1);
  345.         if (!c) break;        // done
  346.  
  347.         len=unmangledst-(unmanglebuf+LOOKBACK);
  348.         if (len>BLOCKSIZE)
  349.             {
  350.             // output this block
  351.             fwrite(unmanglebuf+LOOKBACK,1,len,outfile);
  352.  
  353.             // copy back to keep just the LOOKBACK amount
  354.  
  355.             memcpy(unmanglebuf,unmangledst-LOOKBACK,LOOKBACK);
  356.  
  357.             unmangledst=unmanglebuf+LOOKBACK;
  358.             }
  359.  
  360.         if (c & 128)
  361.             {
  362.             // Bit 7 : 1 : BLOCK
  363.             if (c & 64)
  364.                 {
  365.                 // Bit 6 : 1 Block size
  366.                 if (c & 32)
  367.                     {
  368.                     // Bit 5 : 1 Long
  369.                     pt= unmangledst-((c & 31)<<8) -*unmangleGet(unmangleinpoff++,1) -3;    // offset
  370.                     c= *unmangleGet(unmangleinpoff++,1) + 5;                        // size
  371.  
  372.                     while (c--)
  373.                         *unmangledst++=*pt++;
  374.                     }
  375.                 else
  376.                     {
  377.                     // Bit 5 : 0 Medium
  378.                     pt= unmangledst-((c & 3)<<8) -*unmangleGet(unmangleinpoff++,1) -3;    // offset
  379.                     c= ((c>>2) & 7) + 4;                    // size
  380.                     while (c--)
  381.                         *unmangledst++=*pt++;
  382.  
  383.                     }
  384.                 }
  385.             else
  386.                 {
  387.                 // Bit 6 : 0 : Short
  388.                 pt= unmangledst-(c & 63) -3;
  389.                 *unmangledst    = *pt;
  390.                 *(unmangledst+1)= *(pt+1);
  391.                 *(unmangledst+2)= *(pt+2);
  392.                 unmangledst+=3;
  393.                 }
  394.             }
  395.         else
  396.             {
  397.             // Bit 7 : 0
  398.             if (c & 64)
  399.                 {
  400.                 // Bit 6 : 1 Seq/Diff or String
  401.                 if (c & 32)
  402.                     {
  403.                     // Bit 5 : 1 : Sequence
  404.                         if (c & 16)
  405.                         {
  406.                         // Bit 4 : 1 : Word sequence
  407.                         c= (c & 15) + 2;    // bits 3-0 = len 2->17
  408.                         v= *(short *)(unmangledst-2);
  409.                         while (c--)
  410.                             {
  411.                             *(short *)unmangledst=(short)v;
  412.                             unmangledst+=2;
  413.                             }
  414.                         }
  415.                     else
  416.                         {
  417.                         // Bit 4 : 0 : Byte sequence
  418.                         c= (c & 15) + 3;    // bits 3-0 = len 3->18
  419.                         v= *(unmangledst-1);
  420.                         while (c--)
  421.                             *unmangledst++=(signed char) v;
  422.                         }
  423.                     }
  424.                 else
  425.                     {
  426.                     // Bit 5 : 0 : Difference
  427.                         if (c & 16)
  428.                         {
  429.                         // Bit 4 : 1 : Word difference
  430.                         c= (c & 15) + 2;            // bits 3-0 = len 2->17
  431.                         u= *(short *)(unmangledst-2);        // start word
  432.                         v= u -*(short *)(unmangledst-4);    // dif
  433.                         while (c--)
  434.                             {
  435.                             u+=v;
  436.                             *(short *)unmangledst=(short)u;
  437.                             unmangledst+=2;
  438.                             }
  439.                         }
  440.                     else
  441.                         {
  442.                         // Bit 4 : 0 : Byte difference
  443.                         c= (c & 15) + 3;    // bits 3-0 = len 3->18
  444.                         u= *(unmangledst-1);        // start byte
  445.                         v= u - *(unmangledst-2);    // dif
  446.                         
  447.                         while (c--)
  448.                             {
  449.                             u+=v;
  450.                             *unmangledst++=(char)u;
  451.                             }
  452.                         }
  453.                     }
  454.                 }
  455.             else
  456.                 {
  457.                 // Bit 6 : 0 : String
  458.                 c &= 63;    // len
  459.                 memcpy(unmangledst,unmangleGet(unmangleinpoff,c),c);
  460.                 unmangledst+=c;
  461.                 unmangleinpoff+=c;
  462.                 }
  463.             }
  464.         }
  465.  
  466. //    output any remaining stuff
  467.     
  468.     len=unmangledst-(unmanglebuf+LOOKBACK);
  469.     if (len>0)
  470.         fwrite(unmanglebuf+LOOKBACK,1,len,outfile);
  471.  
  472.     fclose(unmanglefile);
  473.  
  474.     free(unmanglebuf);
  475.     free(unmangleinbuf);
  476.  
  477.     return(EZERO);
  478.     }
  479.  
  480.  
  481. //************************************************************************************************
  482.  
  483.  
  484. unsigned char *
  485. unmangleGet(unsigned long offset,unsigned long size)
  486.     {
  487.     // Returns a pointer to the mangled data at 'offset' in the mangled file
  488.     // 'size' bytes must be available
  489.  
  490.     if (offset<unmanglebufpos || size+offset>unmanglebufpos+INPUTBLOCK)
  491.         {
  492.         unmanglebufpos=offset;
  493.         fseek(unmanglefile,unmanglebufpos,SEEK_SET);
  494.         fread(unmangleinbuf,1,INPUTBLOCK,unmanglefile);
  495.         }
  496.  
  497.     return(unmangleinbuf+offset-unmanglebufpos);
  498.  
  499.     }
  500.